/* Made by Jared Kohr
 * Last Modified: 7/23/2017
 * Description: This program was created to launch Citrix storefront applications that Citrix via the web.
 * As of 7/23/2017, this program uses Selenium automation software which should hopefully provide more reliable results.
 */
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Interactions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

// import the function in your class

namespace Citrix_Storefront_Auto_App_Web_Launcher
{
    class Program
    {
        private static IWebDriver driver;

        private static Boolean silentMode = false;
        private static Boolean ignoreErrorsMode = false;
        private static int tabsToPress = 1; // default is 1 tab press
        private static int customWaitTime = 0; // deault is no waiting at all.
        private static String storefrontURL=""; //blank web page is default


        static void Main(string[] args)
        {
            int i = args.Length - 1;

            if (i > 0)
            {
                storefrontURL = args[0];

                while (i > 0)
                {
                    if (args[i] == "Silent:True")
                        EnableSilentMode();
                    else if (args[i] == "IgnoreErrors:True")
                        EnableIgnoreErrorsMode();
                    else if (args[i] == "MultiTab:True")
                    {
                        try
                        {
                            tabsToPress = Int32.Parse(args[i + 1]);
                            Console.WriteLine("\nMultiTab mode enabled. Tabs to press: " + tabsToPress);
                        }
                        catch
                        {
                            WriteError("\nTab arguement invalid. Not a valid integer value. Verify the value after Tabs:True is a valid interger value.\n\nApplication terminated.");
                        }
                    }
                    else if (args[i] == "CustomWaitTime:True")
                    {
                        try
                        {
                            customWaitTime = Int32.Parse(args[i + 1]);
                            Console.WriteLine("\nCustomWaitTime mode enabled. Waiting " + customWaitTime + " seconds.");
                            customWaitTime = customWaitTime * 1000;
                        }
                        catch
                        {
                            WriteError("\nTab arguement invalid. Not a valid integer value. Verify the value after Tabs:True is a valid interger value.\n\nApplication terminated.");
                        }
                    }
                    else if (args[i] == "RestartCitrix:True")
                    {
                        // Try to kill all known Citrix processes
                        try
                        {
                            Console.WriteLine("\nAttempting to kill Citrix process...");
                            Process[] proc;
                            try
                            {
                                proc = Process.GetProcessesByName("iexplore");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close iexplore.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("Receiver");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close Receiver.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("SelfServicePlugin");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close SelfServicePlugin.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("SelfService");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close SelfService.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("wfcrun32");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close wfcrun32.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("wfica32");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close wfica32.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("concentr");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close concentr.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("AuthManSvr");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close AuthManSvr.exe");
                            }
                            try
                            {
                                proc = Process.GetProcessesByName("pnagent");

                                int n = 0;
                                while (n < proc.Length)
                                {
                                    proc[n].Kill();
                                    n++;
                                }
                            }
                            catch
                            {
                                WriteWarning("\nFailed to find or close pnagent.exe");
                            }
                            Thread.Sleep(5000);
                            WriteSuccess("\nSuccessfully killed Citrix processes, attempting to restart now...");
                        }
                        catch (Exception e)
                        {
                            WriteError("\nFailed to terminate Citrix processes.\n\nException: " + e);
                        }
                    }
                    i--;
                }
            }
            else
            {
                WriteError("No arguement provided.\n\nPlease note the first arguement should be set to the Citrix storefront URL you wish to have automatically started.");
            }
            //Gets IE location for 32-bit version in the 32-bit OS and the 64-bit OS.
            //Checks for 64-bit (Program Files (x86)) first since 64-bit OS also has iexplore.exe in (Program Files), same as 32-bit OS
            //String internetExplorer32bit = @"C:\Program Files\Internet Explorer\iexplore.exe";
            //String internetExplorer64bit = @"C:\Program Files (x86)\Internet Explorer\iexplore.exe";
            try
            {
                OpenWebApp();
            }
            catch (Exception e)
            {
                WriteError("Unable to launch Internet Explorer. Error: "+e);
            }
            /*if (File.Exists(internetExplorer64bit))
            {
                WriteSuccess("\nAttempting to launch Citrix...");
                Process proc = new Process();
                proc.StartInfo.FileName = internetExplorer64bit;
                proc.StartInfo.Arguments = storefrontURL;
                try
                {
                    proc.Start();
                }
                catch
                {
                    WriteError("\nFailed to start Internet Explorer with the given arguements!\n\nApplication terminated.");
                }
                IntPtr h = proc.MainWindowHandle;
                proc.WaitForInputIdle();
                Thread.Sleep(customWaitTime);
                while (tabsToPress > 0)
                {
                    SetForegroundWindow(h);
                    SendKeys.SendWait("{TAB}");
                    Thread.Sleep(1000);
                    tabsToPress--;
                }
                SetForegroundWindow(h);
                SendKeys.SendWait("{ENTER}");
            }*/
            /* else if (File.Exists(internetExplorer32bit))
             {
                 WriteSuccess("\nAttempting to launch Citrix...");
                 Process proc = new Process();
                 proc.StartInfo.FileName = internetExplorer32bit;
                 proc.StartInfo.Arguments = storefrontURL;
                 try
                 {
                     proc.Start();
                 }
                 catch
                 {
                     WriteError("\nFailed to start Internet Explorer with the given arguements!\n\nApplication terminated.");
                 }
                 IntPtr h = proc.MainWindowHandle;
                 proc.WaitForInputIdle();
                 Thread.Sleep(customWaitTime);
                 while (tabsToPress > 0)
                 {
                     SetForegroundWindow(h);
                     SendKeys.SendWait("{TAB}");
                     Thread.Sleep(1000);
                     tabsToPress--;
                 }
                 SetForegroundWindow(h);
                 SendKeys.SendWait("{ENTER}");
             }*/
            /*else
            {
                WriteError("\nInternet Explorer not found!\n\nApplication terminated.");
            }*/
            Console.WriteLine("\nAll files have been processed.");
            Console.WriteLine("\n\nPress [enter] to exit.");
            //Console.ResetColor();
            if (!GetSilentModeEnabled())
                Console.ReadLine();
            Environment.Exit(0);
        }

        public static void WriteError(string message)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message);
            Console.ResetColor();
            Console.WriteLine("\n\nPress [enter] to exit.");
            if (!GetIgnoreErrorsModeEnabled())
                Console.ReadLine();
            Environment.Exit(0);
        }

        public static void WriteWarning(string message)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(message);
            Console.ResetColor();
        }

        public static void WriteSuccess(string message)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(message);
            Console.ResetColor();
        }

        public static string GetCurrentUser()
        {
            string result = string.Empty;

            try
            {
                result = Environment.UserName.ToString();
                //result = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
            }
            catch { }

            return result;
        }

        private static void EnableSilentMode()
        {
            silentMode = true;
            Console.WriteLine("\nSilent mode enabled.");
        }

        private static Boolean GetSilentModeEnabled()
        {
            return silentMode;
        }

        private static void EnableIgnoreErrorsMode()
        {
            ignoreErrorsMode = true;
            Console.WriteLine("\nIgnore errors mode enabled.");
        }

        private static Boolean GetIgnoreErrorsModeEnabled()
        {
            return ignoreErrorsMode;
        }

        private static void OpenWebApp()
        {
            var driverService = InternetExplorerDriverService.CreateDefaultService();
            driverService.HideCommandPromptWindow = true;

            InternetExplorerOptions options = new InternetExplorerOptions();
            options.IntroduceInstabilityByIgnoringProtectedModeSettings = true; // Prevents Protected Mode Error. This must be enabled as security team does not allow us to modify IE protected mode settings.
            options.IgnoreZoomLevel = true; // Prevents Selenium Zoom Level Error
            //options.AddArguments("disable-infobars"); // Specific to Chrome

            driver = new InternetExplorerDriver(driverService, options);

            driver.Url = storefrontURL;
            try
            {
            //driver.FindElement(By.ClassName("storeapp-details-link")).Click();
            Thread.Sleep(2000);

            //IWebElement element = driver.FindElement(By.ClassName("storeapp-name"));
            if (customWaitTime > 0)
                Thread.Sleep(customWaitTime);

            Actions actions = new Actions(driver);

            while (tabsToPress > 0)
            {
                //SetForegroundWindow(h);
                actions.SendKeys(OpenQA.Selenium.Keys.Tab);
                tabsToPress--;
            }
            actions.SendKeys(OpenQA.Selenium.Keys.Enter);
            actions.Perform();

            //IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
            //jse.ExecuteScript("arguments[0].scrollIntoView()", element);
            //driver.FindElement(By.ClassName("storeapp-details-link")).Click();
            //driver.SendKeys(OpenQA.Selenium.Keys.ArrowUp);
            //    IWebElement username = driver.FindElement(By.Id("username_input"));
            //string configUsername = ConfigurationManager.AppSettings["Username"];
            //string configUsername = Properties.Settings.Default.Username;
            //    if (configUsername == null || configUsername == "")
            //       username.SendKeys(Shared.GetCurrentUser());
            //   else
            //       username.SendKeys(configUsername);
            }
            catch
                { }
               // this.WindowState = FormWindowState.Minimized;
                try
                {
                    Process[] proc = Process.GetProcessesByName("IEDriverServer");

                    int n = 0;
                    while (n < proc.Length)
                    {
                        proc[n].Kill();
                        n++;
                    }
                }
                catch { }
        }

        //[DllImport("User32.dll")]
        //private static extern int SetForegroundWindow(IntPtr hWnd);
    }
}
